package com.wondream.myframework.design_pattern.strategy.loan;

import com.wondream.myframework.design_pattern.strategy.loan.contract.ContractStrategy;
import com.wondream.myframework.design_pattern.strategy.loan.credit.CreditStrategy;
import com.wondream.myframework.design_pattern.strategy.loan.draw.DrawStrategy;
import com.wondream.myframework.design_pattern.strategy.loan.order.DefaultOrderStrategy;
import com.wondream.myframework.design_pattern.strategy.loan.credit.DefaultCreditStrategy;
import com.wondream.myframework.design_pattern.strategy.loan.contract.DefaultContractStrategy;
import com.wondream.myframework.design_pattern.strategy.loan.draw.DefaultDrawStrategy;
import com.wondream.myframework.design_pattern.strategy.loan.order.OrderStrategy;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

public class StrategyFactory<T> {

    private static final Map<Class, Object> singletonObjects = new HashMap<>();

    static {
        singletonObjects.put(DefaultOrderStrategy.class, new DefaultOrderStrategy());
        singletonObjects.put(DefaultCreditStrategy.class, new DefaultCreditStrategy());
        singletonObjects.put(DefaultContractStrategy.class, new DefaultContractStrategy());
        singletonObjects.put(DefaultDrawStrategy.class, new DefaultDrawStrategy());
    }

    private static Map<FlowTemplateEnum, Object> orderStrategyMap = new HashMap<>();
    private static Map<FlowTemplateEnum, Object> creditStrategyMap = new HashMap<>();
    private static Map<FlowTemplateEnum, Object> contractStrategyMap = new HashMap<>();
    private static Map<FlowTemplateEnum, Object> drawStrategyMap = new HashMap<>();

    static {
        singletonObjects.entrySet().iterator().forEachRemaining(entry -> {
            if (entry.getValue() instanceof OrderStrategy) {
                doPut(entry, orderStrategyMap);
            }
            if (entry.getValue() instanceof CreditStrategy) {
                doPut(entry, creditStrategyMap);
            }
            if (entry.getValue() instanceof ContractStrategy) {
                doPut(entry, contractStrategyMap);
            }
            if (entry.getValue() instanceof DrawStrategy) {
                doPut(entry, drawStrategyMap);
            }

        });
    }

    private static Map<Class, Map<FlowTemplateEnum, Object>> strategyFactoryMapping = new HashMap<>();

    static {
        strategyFactoryMapping.put(OrderStrategy.class, orderStrategyMap);
        strategyFactoryMapping.put(CreditStrategy.class, creditStrategyMap);
        strategyFactoryMapping.put(ContractStrategy.class, contractStrategyMap);
        strategyFactoryMapping.put(DrawStrategy.class, drawStrategyMap);
    }

    private static void doPut(Map.Entry<Class, Object> entry, Map<FlowTemplateEnum, Object> objectMap) {
        StrategyServiceAnnotation annotation = (StrategyServiceAnnotation) entry.getKey().getAnnotation(StrategyServiceAnnotation.class);
        if (annotation != null) {
            objectMap.put(annotation.flowTemplate(), entry.getValue());
        }
    }

    /**
     * 获取策略类
     */
    public static Object getStrategy(Class clazz, String flowId) {
        return strategyFactoryMapping.get(clazz).get(FlowTemplateEnum.getFlowTemplateByFlowId(flowId));
    }

    public static void main(String[] args) {
        OrderStrategy strategy = (OrderStrategy) StrategyFactory.getStrategy(OrderStrategy.class, FlowTemplateEnum.FLOW_TEMPLATE_DEFAULT.getFlowId());
        strategy.applyOrder();
    }
}
